import { MemoryStore, SessionData } from "express-session";
import { DependencyContainer, injectable } from "tsyringe";
import { EventEmitter } from 'events'
import { useEntityManager } from "./plugin";
EventEmitter.setMaxListeners(10000)
@injectable()
export class PgMemoryStore extends MemoryStore {
    constructor(private injector: DependencyContainer) {
        super();
    }
    get(sid: string, callback: (err: any, session?: SessionData | null) => void): void {
        useEntityManager(async m => {
            const r = m.getRepository('ims_session')
            const session = await r.findOne({ where: { sessionid: sid } })
            if (session) return callback(null, session.data)
            return callback(null, null)
        })
    }
    set(sid: string, session: SessionData, callback?: (err?: any) => void): void {
        useEntityManager(async m => {
            const r = m.getRepository('ims_session')
            const item = await r.findOne({ where: { sessionid: sid } })
            if (item) await r.update(item.id, { data: session })
            else await r.insert({ sessionid: sid, data: session })
            return callback(null)
        })
    }
    destroy(sid: string, callback?: (err?: any) => void): void {
        useEntityManager(async m => {
            const r = m.getRepository('ims_session')
            const session = await r.findOne({ where: { sessionid: sid } })
            if (session) await r.delete(session.id)
            return callback(null)
        })
    }
    all(callback: (err: any, obj?: { [sid: string]: SessionData } | null) => void): void {
        useEntityManager(async m => {
            const r = m.getRepository('ims_session')
            const sessions = await r.find()
            const obj = {};
            sessions.map(session => {
                Reflect.set(obj, session.sessionid, session.data)
            })
            return callback(null, obj)
        })
    }
    length(callback: (err: any, length?: number) => void): void {
        useEntityManager(async m => {
            const r = m.getRepository('ims_session')
            const length = await r.count()
            return callback(null, length)
        })
    }
    clear(callback?: (err?: any) => void): void {
        useEntityManager(async m => {
            const r = m.getRepository('ims_session')
            const length = await r.clear()
            return callback(null)
        })
    }
    touch(sid: string, session: SessionData, callback?: () => void): void {
        useEntityManager(async m => {
            const r = m.getRepository('ims_session')
            const item = await r.findOne({ where: { sessionid: sid } })
            if (item) await r.update(item.id, { data: session })
            else await r.insert({ sessionid: sid, data: session })
            return callback()
        })
    }
}
